﻿using AntDesign;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Xms.Abp.Authorization;
using Xms.Abp.ObjectMapping;
using Volo.Abp.Users;

namespace Xms.Abp.AntDesignUI;

public abstract class AbpAntComponentBase : AntDomComponentBase
{
    [Inject]
    protected IAbpLazyServiceProvider LazyServiceProvider { get; set; }

    protected TService LazyInject<TService>()
    {
        return LazyServiceProvider.LazyGetRequiredService<TService>();
    }

    protected TService LazyInject<TService>(Type type)
    {
        return (TService)LazyServiceProvider.LazyGetRequiredService(type);
    }

    protected IStringLocalizerFactory StringLocalizerFactory => LazyInject<IStringLocalizerFactory>();

    protected IStringLocalizer L
    {
        get
        {
            if (_localizer == null)
            {
                _localizer = CreateLocalizer();
            }

            return _localizer;
        }
    }
    private IStringLocalizer _localizer;

    protected Type LocalizationResource
    {
        get => _localizationResource;
        set
        {
            _localizationResource = value;
            _localizer = null;
        }
    }
    private Type _localizationResource = typeof(DefaultResource);

    protected ILogger Logger => _lazyLogger.Value;
    private Lazy<ILogger> _lazyLogger => new Lazy<ILogger>(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true);

    protected ILoggerFactory LoggerFactory => LazyInject<ILoggerFactory>();

    protected IXmsAuthorizationService AuthorizationService => LazyInject<IXmsAuthorizationService>();

    protected ICurrentUser CurrentUser => LazyInject<ICurrentUser>();

    protected IXmsObjectMapper ObjectMapper
    {
        get
        {
            if (ObjectMapperContext == null)
            {
                return LazyInject<IXmsObjectMapper>();
            }
            return LazyInject<IXmsObjectMapper>(typeof(IXmsObjectMapper<>).MakeGenericType(ObjectMapperContext));
        }
    }

    protected Type ObjectMapperContext { get; set; }

    protected virtual IStringLocalizer CreateLocalizer()
    {
        if (LocalizationResource != null)
        {
            return StringLocalizerFactory.Create(LocalizationResource);
        }

        var localizer = StringLocalizerFactory.CreateDefaultOrNull();
        if (localizer == null)
        {
            throw new AbpException($"Set {nameof(LocalizationResource)} or define the default localization resource type (by configuring the {nameof(AbpLocalizationOptions)}.{nameof(AbpLocalizationOptions.DefaultResourceType)}) to be able to use the {nameof(L)} object!");
        }

        return localizer;
    }
}
